package com.elibrary;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.SubMenu;
import com.actionbarsherlock.view.Window;
import com.elibrary.imageloader.ImageLoader;
import nimo.elibrary.actions.Booklist;
import nimo.elibrary.db.model.BookmarkDataSource;
import nimo.elibrary.db.model.HistoryDataSource;
import nimo.elibrary.db.model.User;
import nimo.elibrary.db.model.UserDataSource;
import nimo.elibrary.json.model.book.Book;
import nimo.elibrary.json.model.book.BookList;
import nimo.elibrary.json.model.book.InPress;
import nimo.elibrary.json.model.history.HistoryList;

/**
 * Created with IntelliJ IDEA.
 * User: Enkuso
 * Date: 12/11/12
 * Time: 2:49 PM
 * To change this template use File | Settings | File Templates.
 */
public class BaseActivity extends SherlockFragmentActivity {
    protected UserDataSource userDataSource;
    protected BookmarkDataSource bookmarkDataSource;
    protected HistoryDataSource historyDataSource;
    protected BookstoreApplication app;
    protected MenuItem signin;
    protected int mStackLevel = 1;
    protected ProgressDialog mDialog;
    protected int currentFragment;
    protected Book currentlyViewingBook;

    /**
     * Variables for search action
     */
    protected String searchQuery = "";
    protected boolean[] selectedFilterItems = {true, true, true, true, true, false};
    protected String filteringField = "";
    protected String orderingField = "";
    protected String currentOrder = "ASC";
    public static String ASC = "ASC";
    public static String DESC = "DESC";
    protected BooklistFragment booklistFragment;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

        userDataSource = new UserDataSource(this);
        bookmarkDataSource = new BookmarkDataSource(this);
        historyDataSource = new HistoryDataSource(this);
        app = (BookstoreApplication)getApplicationContext();
        mDialog = new ProgressDialog(this);

        getSupportActionBar().setDisplayShowTitleEnabled(false);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setIcon(R.drawable.logo);
        setSupportProgressBarIndeterminateVisibility(false);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        SubMenu subMenu1 = menu.addSubMenu("Үндсэн цэс");
        subMenu1.add(Constants.MENU_LIBRARY);
        subMenu1.add(Constants.MENU_MYBOOKS);
        subMenu1.add(Constants.MENU_COMMENTS);
        subMenu1.add(Constants.MENU_PROFILE);
        subMenu1.add(Constants.MENU_BOOKMARK);
        subMenu1.add(Constants.MENU_HISTORY);

        MenuItem subMenu1Item = subMenu1.getItem();
        subMenu1Item.setIcon(R.drawable.ic_menu);
        subMenu1Item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);

        signin = menu.add(Constants.MENU_SIGNIN);
        if(app.isLogged()) {
            setSignoutMenuBtn();
        } else {
            setSigninMenuBtn();
        }
        signin.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
        menu.add(Constants.MENU_SEARCH)
                .setIcon(R.drawable.ic_search_inverse)
                .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);

        menu.add(Constants.MENU_ABOUT)
                .setIcon(R.drawable.ic_refresh_inverse)
                .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if (item.toString().equals(Constants.MENU_ABOUT))
            gotoAboutApp(null);
        else if (item.toString().equals(Constants.MENU_SEARCH))
            gotoSearch(null);
        else if (item.toString().equals(Constants.MENU_SIGNIN))
            gotoSignin(null);
        else if (item.toString().equals(Constants.MENU_SIGNUP))
            gotoSignup(null);
        else if (item.toString().equals(Constants.MENU_SIGNOUT))
            Signout(null);
        else if (item.toString().equals(Constants.MENU_BOOKMARK))
            gotoBookmark(null);
        else if (item.toString().equals(Constants.MENU_HISTORY))
            gotoHistory(null);
        else if (item.toString().equals(Constants.MENU_LIBRARY))
            gotoLibrary(null);
        else if (item.toString().equals(Constants.MENU_PROFILE))
            gotoProfile(null);
        else if (item.toString().equals(Constants.MENU_COMMENTS))
            gotoComments(null);
        else if (item.toString().equals(Constants.MENU_MYBOOKS))
            gotoMyBooks(null);
        else if(item.getItemId() == android.R.id.home)
            gotoBack(null);

        //This uses the imported MenuItem from ActionBarSherlock
        //Toast.makeText(this, "Got click: " + item.toString(), Toast.LENGTH_SHORT).show();
        return super.onOptionsItemSelected(item);
    }

    protected void addFragmentToStack(Fragment newFragment) {

        // Add the fragment to the activity, pushing this transaction
        // on to the back stack.
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.setCustomAnimations(R.anim.fragment_slide_left_enter,
                R.anim.fragment_slide_left_exit,
                R.anim.fragment_slide_right_enter,
                R.anim.fragment_slide_right_exit);
        ft.replace(R.id.main_fragment, newFragment);
        ft.addToBackStack(null);
        ft.commit();
    }

    protected void setSigninMenuBtn(){
        signin.setTitle(Constants.MENU_SIGNIN);
        signin.setIcon(R.drawable.ic_compose_inverse);
    }

    protected void setSignoutMenuBtn(){
        signin.setTitle(Constants.MENU_SIGNOUT);
        signin.setIcon(R.drawable.ic_compose_inverse);
    }

    public void gotoAboutApp(View view) {
        // TODO Auto-generated method stub

    }

    public void gotoSearch(View view) {
        // TODO Auto-generated method stub

    }

    public void gotoLibrary(View view) {
        if(hasInternetConnection()) {
            new LibraryTask().execute("1");
        }
    }

    public void gotoProfile(View view) {
        if(isSignedIn()){
            // TODO display profile fragment
        }
    }

    public void gotoComments(View view) {
        // TODO Auto-generated method stub

    }

    public void gotoMyBooks(View view) {
        // TODO Auto-generated method stub

    }

    public void gotoBack(View view) {
        getSupportFragmentManager().popBackStackImmediate();
    }

    /**
     * Нэвтэрсэн хэрэглэгч гарах. (Signout)
     * @param view
     */
    public void Signout(View view) {
        if(app.isLogged()){
            userDataSource.open();
            User user = userDataSource.getLoggedUser();
            userDataSource.removeUserToken(user.username);
            userDataSource.close();
            app.setLoggedOut();
            Toast.makeText(this, R.string.signout_success, Toast.LENGTH_SHORT).show();

            setSigninMenuBtn();
        }
        else {
            Toast.makeText(this, R.string.signout_success, Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * Хэрэглэгч нэвтрэх цонхонд очих
     * @param view
     */
    public void gotoSignin(View view) {
        if(!app.isLogged()){
            //Intent signin = new Intent("com.elibrary.SIGNIN");
            //startActivity(signin);

            mStackLevel++;
            // Instantiate a new fragment.
            Fragment newFragment = new SigninFragment(mStackLevel);
            addFragmentToStack(newFragment);
        }
        else {
            Toast.makeText(this, R.string.already_signed_in, Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * Хэрэглэгч бүртгүүлэх цонхонд очих
     * @param view
     */
    public void gotoSignup(View view) {
        if(!app.isLogged()){
            //Intent signup = new Intent("com.elibrary.SIGNUP");
            //startActivity(signup);

            mStackLevel++;
            // Instantiate a new fragment.
            Fragment newFragment = new SignupFragment(mStackLevel);
            addFragmentToStack(newFragment);
        }
        else {
            Toast.makeText(this, R.string.already_signed_in, Toast.LENGTH_SHORT).show();
        }
    }

    public void gotoResetPassword(View btn)
    {
        //Intent reset_pwd= new Intent("com.elibrary.RESETPWD");
        //startActivity(reset_pwd);

        mStackLevel++;
        // Instantiate a new fragment.
        Fragment newFragment = new ResetPasswordFragment(mStackLevel);
        addFragmentToStack(newFragment);
    }

    /**
     * Хэрэглэгч History цонхонд очих
     * @param view
     */
    public void gotoHistory(View view) {
        if(hasInternetConnection2() && app.isLogged()) {
            new LongHistoryTask().execute("1", app.getUserToken());
        } else {
            new HistoryTask().execute();
        }
        //if(app.isLogged()){
        //    // TODO: start History activity
        //    /*
        //    Intent history = new Intent("com.elibrary.HISTORY");
        //    startActivity(history);
        //    */
        //}
        //else {
        //    // TODO: Хэрэглэгчид нэвтрэх/бүртгүүлэх үйлдэл санал болгох
        //    Toast.makeText(this, R.string.must_be_signed, Toast.LENGTH_SHORT).show();
        //}
    }

    /**
     * Хэрэглэгч Bookmark цонхонд очих
     * @param view
     */
    public void gotoBookmark(View view) {
        new BookmarkTask().execute();
        //if(app.isLogged()){
        //    // TODO: start Bookmark activity
        //    /*
        //    Intent bookmark = new Intent("com.elibrary.BOOKMARK");
        //    startActivity(bookmark);
        //    */
        //}
        //else {
        //    // TODO: Хэрэглэгчид нэвтрэх/бүртгүүлэх үйлдэл санал болгох
        //    Toast.makeText(this, R.string.must_be_signed, Toast.LENGTH_SHORT).show();
        //}
    }

    /**
     * Номын дэлгэрэнгүй мэдээлэл үзэх цонхонд шилжих
     * @param view
     */
    public void gotoBookDetail(View view, String bookId) {
        // TODO fragment
        if(hasInternetConnection()){
            new BookDetailTask().execute(bookId, app.getUserToken());
            //Intent bookDetail = new Intent("com.elibrary.BOOKDETAIL");
            //bookDetail.putExtra("book_id", bookId);
            //startActivity(bookDetail);
        }
    }

    /**
     * Bookmark хийгдсэн номын дэлгэрэнгүй мэдээлэл үзэх цонхонд шилжих
     * @param view
     */
    public void gotoOfflineBookDetail(View view, String bookId) {
        Book book;
        bookmarkDataSource.open();
        book = bookmarkDataSource.getBook(bookId);
        bookmarkDataSource.close();
        if(book != null ) {
            mStackLevel++;
            OfflineBookDetailFragment newFragment = new OfflineBookDetailFragment(mStackLevel, book);
            addFragmentToStack(newFragment);
        }
    }

    protected void setTvErrorMessage(String msg) {
        TextView tv = (TextView)findViewById(R.id.tvError);
        tv.setVisibility(View.VISIBLE);
        tv.setText(msg);
    }

    protected void setTvErrorMessage(int res_id) {
        TextView tv = (TextView)findViewById(R.id.tvError);
        tv.setText(getString(res_id));
        tv.setVisibility(View.VISIBLE);
    }

    /**
     * Интернэт холболт байгаа эсэхийг шалгах
     */
    protected boolean hasInternetConnection() {
        try {

            ConnectivityManager nInfo = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            nInfo.getActiveNetworkInfo().isConnectedOrConnecting();

            ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo netInfo = cm.getActiveNetworkInfo();
            if (netInfo != null && netInfo.isConnectedOrConnecting()) {
                return true;
            } else {
                AlertDialog alertDialog = new AlertDialog.Builder(this).create();
                alertDialog.setTitle(R.string.no_internet);
                alertDialog.setMessage(getString(R.string.require_internet));
                alertDialog.setIcon(R.drawable.ic_warning);
                alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                    }
                });
                alertDialog.show();
                return false;
            }

        } catch (Exception e) {
            AlertDialog alertDialog = new AlertDialog.Builder(this).create();
            alertDialog.setTitle(R.string.no_internet);
            alertDialog.setMessage(getString(R.string.require_internet));
            alertDialog.setIcon(R.drawable.ic_warning);
            alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                }
            });
            alertDialog.show();
            return false;
        }
    }

    /**
     * Интернэт холболт байгаа эсэхийг шалгах
     */
    protected boolean hasInternetConnection2() {
        try {

            ConnectivityManager nInfo = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            nInfo.getActiveNetworkInfo().isConnectedOrConnecting();

            ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo netInfo = cm.getActiveNetworkInfo();
            if (netInfo != null && netInfo.isConnectedOrConnecting()) {
                return true;
            } else {
                return false;
            }

        } catch (Exception e) {
            return false;
        }
    }

    /**
     * Хэрэглэгчийн бүртгэл шаардлагатай үед харуулах dialog
     */
    protected boolean isSignedIn() {
        if(app.isLogged()) {
            return true;
        }
        AlertDialog alertDialog = new AlertDialog.Builder(this).create();
        alertDialog.setTitle(R.string.signin_or_signup);
        alertDialog.setMessage(getString(R.string.please_signin));
        alertDialog.setIcon(R.drawable.ic_warning);
        alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.signin), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                gotoSignin(null);
            }
        });
        alertDialog.setButton(DialogInterface.BUTTON_NEUTRAL, getString(R.string.signup_btn), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                gotoSignup(null);
            }
        });
        alertDialog.show();
        return false;
    }

    /**
     * Filter button
     */
    public void onFilterButtonClick(View view) {
        final boolean[] selectedItems = selectedFilterItems;

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.select_filter);
        builder.setMultiChoiceItems(R.array.filterItems, selectedFilterItems, new DialogInterface.OnMultiChoiceClickListener() {
            public void onClick(DialogInterface dialog, int whichButton, boolean isChecked) {
                selectedItems[whichButton] = isChecked;
            }
        })
        // Set the action buttons
        .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                selectedFilterItems = selectedItems;
            }
        });
        AlertDialog alert = builder.create();
        alert.show();
    }

    /**
     * Order button
     */
    public void onOrderButtonClick(View view) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.select_order);
        builder.setItems(R.array.orderItems, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                orderingField = Constants.sortFields[which];
            }
        });
        AlertDialog alert = builder.create();
        alert.show();
    }

    /**
     * doSearchButton
     */
    public void doSearchButtonClick(View view) {

    }

    /**
     * Search Button click
     */
    public void onSearchButtonClick(View view) {
        EditText etSearch = (EditText)findViewById(R.id.search_text);
        searchQuery = etSearch.getText().toString();
        doSearch();
    }

    /**
     * doSearch Action
     */
    public void doSearch() {
        String pagenum = "1";
        new SearchTask().execute(pagenum);
    }

    /**
     * change order button (asc/desc)
     */
    public void onChangeOrderButtonClick(View view) {
        if(currentOrder.equals(ASC)) {
            currentOrder = DESC;
            ((Button)view).setText(R.string.search_filter_desc);
        } else {
            currentOrder = ASC;
            ((Button)view).setText(R.string.search_filter_asc);
        }
        doSearch();
    }

    /**
     * bookmark-д нэмэх button
     */
    public void onAddToBookmarkButtonClick(View view) {
        Book book = getCurrentlyViewingBook();
        bookmarkDataSource.open();
        boolean isAdded = bookmarkDataSource.addToBookmark(book.id, book.title, book.cover, book.introduction);
        bookmarkDataSource.close();
        if(isAdded) {
            Toast.makeText(this,"Successfully added to bookmark list",Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this,"Failed",Toast.LENGTH_SHORT).show();
        }
    }
    protected void taskPreExecute() {
        //getSherlock().setProgressBarIndeterminateVisibility(true);
        //mDialog = new ProgressDialog(this); //taking object for progress dialog
        mDialog.setMessage(getString(R.string.please_wait));
        mDialog.show(); //Displaying progressDialog
    }

    protected void taskPostExecute() {
        getSherlock().setProgressBarIndeterminateVisibility(false);
        if (mDialog.isShowing()) {
            mDialog.dismiss();//close the progress Dialog
        }
    }

    class LibraryTask extends AsyncTask<String, Void, BookList> {
        private String page;

        @Override
        protected void onPreExecute() {
            taskPreExecute();
        }

        @Override
        protected BookList doInBackground(String... params) {
            page = params[0];
            BookList booklist = Booklist.getLatestBooks(page);
            return booklist;
        }

        @Override
        protected void onPostExecute(BookList result) {
            // Instantiate a new fragment.
            //Fragment newFragment = new BooklistFragment(mStackLevel, result.getBooksAsArray());
            booklistFragment.setBooks(result.getBooksAsArray());
            if(currentFragment == Constants.FRAGMENT_BOOKLIST) {
                booklistFragment.notifyDataSetChanged();
            } else {
                addFragmentToStack(booklistFragment);
                currentFragment = Constants.FRAGMENT_BOOKLIST;
            }

            taskPostExecute();
        }
    }

    class BookmarkTask extends AsyncTask<String, Void, Book[]> {
        private String page;

        @Override
        protected void onPreExecute() {
            taskPreExecute();
        }

        @Override
        protected Book[] doInBackground(String... params) {
            bookmarkDataSource.open();
            if(bookmarkDataSource.countBookmark() == 0)
                return null;
            Book[] booklist = bookmarkDataSource.getBookmarkList();
            bookmarkDataSource.close();
            return booklist;
        }

        @Override
        protected void onPostExecute(Book[] result) {
            // Instantiate a new fragment.
            if(result != null) {
                BookmarkFragment bookmarkFragment = new BookmarkFragment(mStackLevel++, result);

                addFragmentToStack(bookmarkFragment);
                currentFragment = Constants.FRAGMENT_BOOKMARK;
            } else {
                Toast.makeText(getApplicationContext(), R.string.empty_bookmark, Toast.LENGTH_SHORT).show();
            }
            taskPostExecute();
        }
    }

    class HistoryTask extends AsyncTask<String, Void, Book[]> {
        private String page;

        @Override
        protected void onPreExecute() {
            taskPreExecute();
        }

        @Override
        protected Book[] doInBackground(String... params) {
            historyDataSource.open();
            if(historyDataSource.countHistory() == 0)
                return null;
            Book[] booklist = historyDataSource.getHistoryList();
            historyDataSource.close();
            return booklist;
        }

        @Override
        protected void onPostExecute(Book[] result) {
            // Instantiate a new fragment.
            if(result != null) {
                if(hasInternetConnection2()) {
                    HistoryFragment2 historyFragment = new HistoryFragment2(mStackLevel++, result);
                    addFragmentToStack(historyFragment);
                }
                else {
                    HistoryFragment historyFragment = new HistoryFragment(mStackLevel++, result);
                    addFragmentToStack(historyFragment);
                }
                currentFragment = Constants.FRAGMENT_HISTORY;
            } else {
                Toast.makeText(getApplicationContext(), R.string.empty_history, Toast.LENGTH_SHORT).show();
            }
            taskPostExecute();
        }
    }

    class LongHistoryTask extends AsyncTask<String, Void, Book[]> {
        private String page;
        private String token;

        @Override
        protected void onPreExecute() {
            taskPreExecute();
        }

        @Override
        protected Book[] doInBackground(String... params) {
            // TODO get history information from server
            page = params[0];
            token = params[1];
            HistoryList historylist = nimo.elibrary.actions.User.getHistoryList(token, page);
            if(historylist.books == null)
                return null;
            Book[] booklist = historylist.books.toArray(new Book[historylist.books.size()]);
            return booklist;
        }

        @Override
        protected void onPostExecute(Book[] result) {
            // Instantiate a new fragment.
            if(result != null) {
                HistoryFragment2 historyFragment = new HistoryFragment2(mStackLevel++, result);

                addFragmentToStack(historyFragment);
                currentFragment = Constants.FRAGMENT_HISTORY;
            } else {
                Toast.makeText(getApplicationContext(), R.string.empty_history, Toast.LENGTH_SHORT).show();
            }
            taskPostExecute();
        }
    }

    class BookDetailTask extends AsyncTask<String, Void, Book> {
        private String bookId;
        private String token;

        @Override
        protected void onPreExecute() {
            taskPreExecute();
        }

        @Override
        protected Book doInBackground(String... params) {
            bookId = params[0];
            token = params[1];
            Book book = nimo.elibrary.actions.Book.getBookDetails(bookId, token);
            return book;
        }

        @Override
        protected void onPostExecute(Book book) {
            // Instantiate a new fragment.
            mStackLevel++;
            BookDetailFragment newFragment = new BookDetailFragment(mStackLevel, book);
            addFragmentToStack(newFragment);

            if(book != null){
                //setBook(newFragment, book);
            } else {
                getSupportFragmentManager().popBackStackImmediate();
            }
            taskPostExecute();
        }
    }

    class SearchTask extends AsyncTask<String, Void, BookList> {
        private String page;

        @Override
        protected void onPreExecute() {
            taskPreExecute();
        }

        @Override
        protected BookList doInBackground(String... params) {
            page = params[0];
            // TODO send search request to server
            BookList booklist = Booklist.getSearchResult(searchQuery, page, filteringField, orderingField, currentOrder);
            return booklist;
        }

        @Override
        protected void onPostExecute(BookList booklist) {
            if(booklist != null) {
                // Instantiate a new fragment.
                mStackLevel++;
                //BooklistFragment newFragment = new BooklistFragment(mStackLevel, booklist.getBooksAsArray());
                booklistFragment.setBooks(booklist.getBooksAsArray());
                if(currentFragment == Constants.FRAGMENT_BOOKLIST) {
                    booklistFragment.notifyDataSetChanged();
                } else {
                    addFragmentToStack(booklistFragment);
                    currentFragment = Constants.FRAGMENT_BOOKLIST;
                }
                //addFragmentToStack(newFragment);
            } else {
                Toast.makeText(getApplicationContext(), R.string.search_not_found, Toast.LENGTH_SHORT).show();
            }

            taskPostExecute();
        }
    }

    public Book getCurrentlyViewingBook() {
        return currentlyViewingBook;
    }

    public void setCurrentlyViewingBook(Book currentlyViewingBook) {
        historyDataSource.open();
        historyDataSource.addToHistory(currentlyViewingBook.id, currentlyViewingBook.title, currentlyViewingBook.cover, currentlyViewingBook.introduction);
        historyDataSource.close();

        this.currentlyViewingBook = currentlyViewingBook;
    }
}
